﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace BenevolentSun
{
    public class Tween
    {

        /// <summary>
        /// An object that can be associated with this tween, this is purely user data.
        /// </summary>
        public Object Object;

        protected double delay = 0f;
        public double Delay
        {
            set { delay = value; }
        }

        protected float start;
        public float Start
        {
            get { return start; }
            set { start = value; }
        }

        protected float end;
        public float End
        {
            get { return end; }
            set { end = value; }
        }

        protected float value;
        public float Value
        {
            get { return value; }
        }

        protected double seconds;
        public double Seconds
        {
            get { return seconds; }
        }

        protected double elapsed = 0;

        protected LoopType loopType;

        public Boolean IsFinished
        {
            get { return loopType == LoopType.None && elapsed == seconds; }
        }


        public Tween(float start, float end, double delay, double seconds, LoopType loopType)
        {
            this.delay = delay;
            this.start = start;
            this.end = end;
            this.seconds = seconds;
            this.loopType = loopType;
        }

        public Tween(float start, float end, double delay, double seconds, LoopType loopType, Object obj)
        {
            this.delay = delay;
            this.start = start;
            this.end = end;
            this.seconds = seconds;
            this.loopType = loopType;
            this.Object = obj;
        }

        public Tween(float start, float end, double seconds, LoopType loopType)
        {
            this.start = start;
            this.end = end;
            this.seconds = seconds;
            this.loopType = loopType;
        }

        public Tween(float start, float end, double seconds, LoopType loopType, Object obj)
        {
            this.start = start;
            this.end = end;
            this.seconds = seconds;
            this.loopType = loopType;
            this.Object = obj;
        }


        public void Update(GameTime gameTime)
        {
            elapsed += gameTime.ElapsedGameTime.TotalSeconds;

            if (elapsed > seconds + delay)
            {
                delay = 0;
                elapsed -= delay;
                if (loopType == LoopType.None)
                {
                    elapsed = seconds;
                    value = end;
                }
                else if (loopType == LoopType.Loop)
                {
                    while (elapsed >= seconds)
                        elapsed -= seconds;
                    value = start + (float)((end - start) * (elapsed / seconds));
                }
                else if (loopType == LoopType.Oscillate)
                {
                    while (elapsed >= seconds)
                    {
                        elapsed -= seconds;
                        float temp = start;
                        start = end;
                        end = temp;
                    }
                    value = start + (float)((end - start) * (elapsed / seconds));
                }
            }
            else
            {
                if (elapsed > delay)
                    value = start + (float)((end - start) * ((elapsed - delay) / seconds));
                else
                    value = start;
            }
        }

        public void AdvanceToEnd()
        {
            elapsed = seconds;
            value = end;
        }


        public enum LoopType
        {
            None,
            Loop,
            Oscillate
        }

    }
}
